
 <!DOCTYPE HTML>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  
    <title>分布式存储系统 知识体系 | Jark&#39;s Blog</title>
    <meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no">
    
    <meta name="author" content="WuChong">
    
    <meta name="description" itemprop="description" content="最近看完了杨传辉老师写的《大规模分布式存储系统》一书，发现里面很多知识点和之前看的《大型网站系统与Java中间件》有很多相通之处，也渐渐加深了我对分布式技术的兴趣。但无奈分布式涵盖范围太广了，分布式存储、分布式计算、CAP理论、Paxos算法、什么GFS、Hadoop、Dynamo、BigTable、Spanner等等，不下点功夫还真不能理顺它们之间的内在关系。所以结合两书以及一些优秀博文，总结了分布式存储的知识体系，为以后打下基础而努力。">
    
    
    <meta name="description" content="最近看完了杨传辉老师写的《大规模分布式存储系统》一书，发现里面很多知识点和之前看的《大型网站系统与Java中间件》有很多相通之处，也渐渐加深了我对分布式技术的兴趣。但无奈分布式涵盖范围太广了，分布式存储、分布式计算、CAP理论、Paxos算法、什么GFS、Hadoop、Dynamo、BigTable、Spanner等等，不下点功夫还真不能理顺它们之间的内在关系。所以结合两书以及一些优秀博文，总结了">
<meta property="og:type" content="article">
<meta property="og:title" content="分布式存储系统 知识体系">
<meta property="og:url" content="http://wuchong.me/blog/2014/08/07/distributed-storage-system-knowledge/">
<meta property="og:site_name" content="Jark's Blog">
<meta property="og:description" content="最近看完了杨传辉老师写的《大规模分布式存储系统》一书，发现里面很多知识点和之前看的《大型网站系统与Java中间件》有很多相通之处，也渐渐加深了我对分布式技术的兴趣。但无奈分布式涵盖范围太广了，分布式存储、分布式计算、CAP理论、Paxos算法、什么GFS、Hadoop、Dynamo、BigTable、Spanner等等，不下点功夫还真不能理顺它们之间的内在关系。所以结合两书以及一些优秀博文，总结了">
<meta property="og:image" content="http://ww4.sinaimg.cn/mw690/81b78497jw1ej3xmerc23j20ss0cstd8.jpg">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="分布式存储系统 知识体系">
<meta name="twitter:description" content="最近看完了杨传辉老师写的《大规模分布式存储系统》一书，发现里面很多知识点和之前看的《大型网站系统与Java中间件》有很多相通之处，也渐渐加深了我对分布式技术的兴趣。但无奈分布式涵盖范围太广了，分布式存储、分布式计算、CAP理论、Paxos算法、什么GFS、Hadoop、Dynamo、BigTable、Spanner等等，不下点功夫还真不能理顺它们之间的内在关系。所以结合两书以及一些优秀博文，总结了">
<meta name="twitter:creator" content="@jarkwu">
<link rel="publisher" href="111190881341800841449">

    
    <link rel="alternative" href="/atom.xml" title="Jark&#39;s Blog" type="application/atom+xml">
    
    
    <link rel="icon" href="/img/favicon.ico">
    
    
    <link rel="apple-touch-icon" href="/img/jacman.jpg">
    <link rel="apple-touch-icon-precomposed" href="/img/jacman.jpg">
    
    <link rel="stylesheet" href="/css/style.css" type="text/css">
</head>

  <body>
    <header>
      <div>
		
			<div id="imglogo">
				<a href="/"><img src="/img/logo.png" alt="Jark&#39;s Blog" title="Jark&#39;s Blog"/></a>
			</div>
			
			<div id="textlogo">
				<h1 class="site-name"><a href="/" title="Jark&#39;s Blog">Jark&#39;s Blog</a></h1>
				<h2 class="blog-motto">当你的才华还撑不起你的野心时，你就应该静下心来学习。</h2>
			</div>
			<div class="navbar"><a class="navbutton navmobile" href="#" title="菜单">
			</a></div>
			<nav class="animated">
				<ul>
					<ul>
					 
						<li><a href="/">首页</a></li>
					
						<li><a href="/archives">归档</a></li>
					
						<li><a href="/about">关于</a></li>
					
					<li>
 					
						<form class="search" action="http://zhannei.baidu.com/cse/search" target="_blank">
							<label>Search</label>
						<input name="s" type="hidden" value= 783281470518440642 ><input type="text" name="q" size="30" placeholder="搜索"><br>
						</form>
					
					</li>
				</ul>
			</nav>			
</div>
    </header>
    <div id="container">
      <div id="main" class="post" itemscope itemprop="blogPost">
  
	<article itemprop="articleBody"> 
		<header class="article-info clearfix">
  <h1 itemprop="name">
    
      <a href="/blog/2014/08/07/distributed-storage-system-knowledge/" title="分布式存储系统 知识体系" itemprop="url">分布式存储系统 知识体系</a>
  </h1>
  <p class="article-author">By
       
		<a href="https://plus.google.com/111190881341800841449?rel=author" title="WuChong" target="_blank" itemprop="author">WuChong</a>
		
  <p class="article-time">
    <time datetime="2014-08-07T06:25:56.000Z" itemprop="datePublished"> 发表于 2014-08-07</time>
    
  </p>
</header>
	<div class="article-content">
		
		<div id="toc" class="toc-article">
			<strong class="toc-title">文章目录</strong>
		
			<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#单机存储引擎"><span class="toc-number">1.</span> <span class="toc-text">单机存储引擎</span></a></li><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#哈希"><span class="toc-number">1.1.</span> <span class="toc-text">哈希</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#B_树"><span class="toc-number">1.2.</span> <span class="toc-text">B 树</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#LSM_树"><span class="toc-number">1.3.</span> <span class="toc-text">LSM 树</span></a></li></ol><li class="toc-item toc-level-2"><a class="toc-link" href="#分布式存储的出现"><span class="toc-number">2.</span> <span class="toc-text">分布式存储的出现</span></a></li><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#数据分布"><span class="toc-number">2.1.</span> <span class="toc-text">数据分布</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#数据复制"><span class="toc-number">2.2.</span> <span class="toc-text">数据复制</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#故障检测"><span class="toc-number">2.3.</span> <span class="toc-text">故障检测</span></a></li></ol><li class="toc-item toc-level-2"><a class="toc-link" href="#一致性模型"><span class="toc-number">3.</span> <span class="toc-text">一致性模型</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#分布式事务"><span class="toc-number">4.</span> <span class="toc-text">分布式事务</span></a></li><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#CAP_原理"><span class="toc-number">4.1.</span> <span class="toc-text">CAP 原理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#NWR_模型"><span class="toc-number">4.2.</span> <span class="toc-text">NWR 模型</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#两阶段提交"><span class="toc-number">4.3.</span> <span class="toc-text">两阶段提交</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Paxos_算法"><span class="toc-number">4.4.</span> <span class="toc-text">Paxos 算法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#小结"><span class="toc-number">4.5.</span> <span class="toc-text">小结</span></a></li></ol><li class="toc-item toc-level-2"><a class="toc-link" href="#分布式系统分类"><span class="toc-number">5.</span> <span class="toc-text">分布式系统分类</span></a></li><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#分布式文件系统"><span class="toc-number">5.1.</span> <span class="toc-text">分布式文件系统</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#分布式键值系统"><span class="toc-number">5.2.</span> <span class="toc-text">分布式键值系统</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#分布式表格系统"><span class="toc-number">5.3.</span> <span class="toc-text">分布式表格系统</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#分布式数据库"><span class="toc-number">5.4.</span> <span class="toc-text">分布式数据库</span></a></li></ol><li class="toc-item toc-level-2"><a class="toc-link" href="#摘录"><span class="toc-number">6.</span> <span class="toc-text">摘录</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#参考资料"><span class="toc-number">7.</span> <span class="toc-text">参考资料</span></a></li></ol>
		
		</div>
		
		<p>最近看完了杨传辉老师写的《大规模分布式存储系统》一书，发现里面很多知识点和之前看的《大型网站系统与Java中间件》有很多相通之处，也渐渐加深了我对分布式技术的兴趣。但无奈分布式涵盖范围太广了，分布式存储、分布式计算、CAP理论、Paxos算法、什么GFS、Hadoop、Dynamo、BigTable、Spanner等等，不下点功夫还真不能理顺它们之间的内在关系。所以结合两书以及一些优秀博文，总结了分布式存储的知识体系，为以后打下基础而努力。由于初入泥潭，必然有些理解不当的地方，若有大神路过还望不吝指教。</p>
<p>本文更像是读书笔记，是对知识点的一个梳理，无奈越写越多，部分知识只能点到为止，具体内容可以查看原书或维基百科。</p>
<h2 id="单机存储引擎">单机存储引擎</h2>
<h3 id="哈希">哈希</h3>
<p>哈希存储引擎是哈希表的持久化实现，支持增、删、改，以及随机读取操作，但不支持顺序扫描，对应的存储系统为键值(Key-Value)存储系统，如 Bitcask。它仅支持追加操作，删除也只是通过标识 value 为特殊值，通过定期合并（Compaction）实现垃圾回收。</p>
<h3 id="B_树">B 树</h3>
<p>B 树存储引擎是 B 树的持久化实现，不仅支持单条记录的增、删、读、改操作，还支持顺序扫描，对应的存储系统是关系数据库。关系数据库中通过索引访问数据，在 Mysql InnoDB 中，有一个称为聚集索引的东西，行的数据存于其中，组织成 B+ 树的结构。更多 B 系树的内容可以参考 <a href="http://taop.marchtea.com/03.02.html" target="_blank" rel="external">这里</a> 。</p>
<h3 id="LSM_树">LSM 树</h3>
<p>LSM 树(Log Structure Merge Tree)存储引擎采用批量转储技术来避免磁盘随机写入。其思想很朴素，就是将对数据的修改增量保持在内存中，达到指定的大小限制后将这些修改操作批量写入磁盘。它广泛应用于互联网的后台存储系统， 例如 Google BigTable、 以及 Facebook 开源的 Cassandra系统。<br><a id="more"></a></p>
<h2 id="分布式存储的出现">分布式存储的出现</h2>
<p>单机存储随着业务的增长会遇到<strong>性能</strong>与<strong>单点故障</strong>问题。通常有两种解决方案：</p>
<ol>
<li>数据分布：就是把数据分块存在不同的服务器上（分库分表）。</li>
<li>数据复制：让所有的服务器都有相同的数据，提供相当的服务。</li>
</ol>
<p>这两种方法都能解决性能上的问题，一般结合使用。而对于数据丢失的问题，我们只能通过第二种方法来完成——数据的冗余存储。但是加入更多的机器，会导致事情变得复杂起来，尤其是分布式事务处理，也就是多台服务器之间的数据如何保持一致性，因为原先单机的 ACID 特性在分布式环境下都用不了了。</p>
<h3 id="数据分布">数据分布</h3>
<p>数据分布主要有两种方式：一种是哈希分布，如一致性哈希（Dynamo）；另一种是顺序分布（BigTable）。考虑因素包括读写场景， 即随机还是顺序， 包括如何保证负载均衡从而提高性能等</p>
<p>传统的哈希分布算法简单的将哈希值与服务器个数做除法取模映射。但是当服务器上下线时，数据的重新分布会带来大量的数据迁移。</p>
<p>因此有了 <strong><a href="http://zh.wikipedia.org/zh-cn/%E4%B8%80%E8%87%B4%E5%93%88%E5%B8%8C" target="_blank" rel="external">一致性哈希算法</a></strong> 。算法思想如下 :给系统中每个节点分配一个随机 token，这些 token 构成一个哈希环。执行数据存放操作时，先计算 Key(主键)的哈希值，然后存放到顺时针方向第一个大于或者等于该哈希值的 token 所在的节点。一致性哈希的优点在于节点加入 / 删除时只会影响到在哈希环中相邻的节点，而对其他节点没影响。增加节点后能很大程度上避免了数据迁移。为了考虑负载均衡，一般还会引入虚拟节点的技术，即一个物理节点会对应着多个虚拟节点（如 Dynamo）。</p>
<h3 id="数据复制">数据复制</h3>
<p>复制协议有两种：<strong>强同步复制</strong>，<strong>异步复制</strong>。 区别在于用户的写请求是否需要同步到备副本才可以返回成功。</p>
<p>一致性和可用性是矛盾的。强同步复制协议保证主备副本之间的一致性，但是当备副本出现故障时会影响系统可用性。异步复制协议的可用性较好，但是一致性得不到保障，主副本出现故障时还有数据丢失的可能。</p>
<p>这两种协议都是将主副本的数据以某种形式（多为操作日志）发送到其他副本，这种复制协议称为基于主副本的复制协议。当然还有基于多个存储节点的复制协议。比如下面会介绍的 Dynamo 系统的 NWR 复制协议。</p>
<h3 id="故障检测">故障检测</h3>
<p>设计分布式系统的前提就是假定服务器时刻肯能发生故障。故障检测主要有心跳和租约两种机制。</p>
<ul>
<li>心跳：假设总控机 A 需要确认工作机 B 是否发生故障，那么总控机 A 每隔一段时间，比如 1 秒，向工作机 B 发送一个心跳包。不足之处是若 A 到 B 网络发生故障，则不能确定是否是 B 不再提供服务。</li>
<li>租约：租约机制就是带有超时时间的一种授权。假设机器 A 需要检测机器 B 是否发生故障，机器 A 可以给机器 B 发放租约，机器 B 持有的租约在有效期内才允许提供服务，否则主动停止服务。机器 B 的租约快要到期的时候向机器 A 重新申请租约。租约机制可以解决上述心跳问题的不足。</li>
</ul>
<h2 id="一致性模型">一致性模型</h2>
<p>说起数据一致性，简单说有三种类型（细分会有很多，此处不展开）：</p>
<ol>
<li><strong>弱一致性（Weak）</strong>：当你写入一个新值后，读操作在各个数据副本上不保证能读出最新值。比如：某些cache系统，网络游戏其它玩家的数据和你没什么关系。</li>
<li><strong>最终一致性（Eventually）</strong>：Eventually 是 Weak 的一种特殊情况。当你写入一个新值后，有可能读不出来，但在某个时间窗口之后保证最终能读出来。比如：DNS，电子邮件、Amazon S3，Google搜索引擎这样的系统。</li>
<li><strong>强一致性（Strong）</strong>：新的数据一旦写入，在任意副本任意时刻都能读到新值。比如：文件系统，RDBMS，Azure Table都是强一致性的。</li>
</ol>
<p>从这三种一致型的模型上来说，我们可以看到，Weak 和 Eventually 一般来说是异步冗余的，而Strong一般来说是同步冗余的，异步的通常意味着更好的性能，但也意味着更复杂的状态控制。同步意味着简单，但也意味着性能下降。</p>
<h2 id="分布式事务">分布式事务</h2>
<p>事务的支持对于业务是非常重要的特性，数据库在单机下的 ACID 事务特性是比较到位的，而一旦进行分库分表后就要面对一致性和可用性的问题了，这就是分布式事务了。</p>
<h3 id="CAP_原理">CAP 原理</h3>
<p>在分布式环境下需要考虑数据的一致性和性能的问题，我们要了解下 <a href="http://zh.wikipedia.org/wiki/CAP%E5%AE%9A%E7%90%86" target="_blank" rel="external">CAP 理论</a>：</p>
<ul>
<li>一致性：所有节点在同一时间具有相同的数据。</li>
<li>可用性：保证每个请求不管成功或者失败都有响应。我理解的是系统的性能。</li>
<li>分区容忍性：系统中任意信息的丢失或失败不会影响系统的继续运作。我理解的是系统的抗故障能力。</li>
</ul>
<p>在分布式系统中，对于这三者不能同时满足。这就是 CAP 理论。</p>
<p>简单地说就是：<br>1）要想让数据避免单点故障，就得写多份数据。<br>2）写多份的问题会导致数据一致性的问题。<br>3）数据一致性的问题又会引发性能问题</p>
<h3 id="NWR_模型">NWR 模型</h3>
<p>NWR是一种在分布式存储系统中用于控制一致性级别的策略，应用于 Amazon Dynamo。NWR 模型将 CAP 的选择权交给了用户，由用户自己选择 CAP 中的哪两个。其中，N 代表 N 个备份，W 代表至少写 W 份才认为成功，R 代表至少要读 R 份才认为成功。</p>
<ul>
<li>如果 W+R&gt;N ，是可以保证强一致性的。因为 W+R &gt; N， 所以 R &gt; N-W，什么意思呢？就是读取的份数必须要大于未成功写的份数，这样至少能读到一份最新值。</li>
<li>如果 W+R&lt;=N，则能够保证最终一致性。</li>
<li>如果我们要高可写的环境，我们可以配置 W=1 R=N。这个时候只要写任何节点成功就认为成功，但是读的时候必须从所有的节点都读出数据。</li>
<li>如果我们要求读的高效率，我们可以配置 W=N R=1。这个时候任何一个节点读成功就认为成功，但是写的时候必须写所有三个节点成功才认为成功。</li>
</ul>
<h3 id="两阶段提交">两阶段提交</h3>
<p>英文 Two Phase Commit，也叫 2PC。两阶段提交经常用于分布式事务，是强一致性算法。简要的说就是分两阶段：</p>
<p>第一阶段，主控节点（协调者）询问所有节点（参与者）是否可以提交操作，参与者回应 yes or no。<br>第二阶段，协调者根据收到的响应，如果所有参与者都回应 yes，则向所有参与者发送“正式提交”的命令。参与者完成后恢复“完成”消息，协调者收集齐各节点的回应后结束这个 Global Transaction。如果有一个拒绝则给所有参与者发送“回滚操作”。参与者回滚成功后回应“回滚完成”，协调者收集各结点的“回滚”回应后，取消这个 Global Transaction。</p>
<p>2PC说白了就是第一阶段做 Vote，第二阶段做决定的一个算法，相对于单库事务来说就是在提交之前多了准备的阶段。但是也存在着问题，其中一个是同步阻塞操作，这个事情必然会非常大地影响性能。另一个主要的问题是在TimeOut上。因此出现了 3PC，主要是将提交过程分为两步，更多描述见 <a href="http://en.wikipedia.org/wiki/Three-phase_commit_protocol" target="_blank" rel="external">Wikipedia</a>。</p>
<h3 id="Paxos_算法">Paxos 算法</h3>
<p>Google Chubby 的作者 Mike Burrows 说过，“世上只有一种一致性算法，那就是 Paxos”，所有其他一致性算法都是Paxos算法的残次版本。</p>
<p>Paxos是一个分布式选举算法， 最大的用途就是保持多个节点数据的一致性。看了好久的 Paxos 算法还是有些迷糊，这里就不给出具体算法了。感兴趣的可以参看 <a href="http://zh.wikipedia.org/zh/Paxos%E7%AE%97%E6%B3%95" target="_blank" rel="external">WikiPedia</a> 以及里面给出的示例。</p>
<p>实际上对于一般的开发人员，我们并不需要了解 Paxos 所有细节及如何实现，只需要知道 Paxos 是一个分布式选举算法就够了。当我们以后遇到相似的问题，知道有这样一个技术，可以正确及优雅地解决技术架构上一些难题就够了。</p>
<h3 id="小结">小结</h3>
<p>Paxos 协议和 2PC 协议在分布式系统中所起的作用并不相同。Paxos 协议用于保证同一个数据分片的多个副本之间的数据一致性。当这些副本分布到不同的数据中心时，这个需求尤其强烈。2PC 协议用于保证属于多个数据分片上的操作的原子性。这些数据分片可能分布在不同的服务器上，2PC 协议保证多台服务器上的操作要么全部成功，要么全部失败。可见 Paxos 的学术地位不一般。</p>
<p>Paxos 协议有两种用法:一种用法是用它来实现全局的锁服务或者命名和配置服务，例如 Google Chubby 以及 Apache Zookeeper 还有全局ID。另外一种用法是用它来将用户数据复制到多个数据中心，例如 Google Megastore 以及 Google Spanner。</p>
<p>2PC 协议最大的缺陷在于无法处理协调者宕机问题。如果协调者宕机，那么，2PC协议中的每个参与者可能都不知道事务应该提交还是回滚，整个协议被阻塞，执行过程中申请的资源都无法释放。因此，常见的做法是将 2PC 和 Paxos 协议结合起来，通过2PC 保证多个数据分片上的操作的原子性，通过 Paxos 协议实现同一个数据分片的多个副本之间的一致性。另外，通过 Paxos 协议解决 2PC 协议中协调者宕机问题。当 2PC协议中的协调者出现故障时，通过 Paxos 协议选举出新的协调者继续提供服务。</p>
<p>下图是几种策略原理的比较，来源于：Google App Engine的 co-founder Ryan Barrett在2009年的google i/o上的演讲《<a href="http://snarfed.org/transactions_across_datacenters_io.html" target="_blank" rel="external">Transaction Across DataCenter</a>》（<a href="http://www.youtube.com/watch?v=srOgpXECblk" target="_blank" rel="external">视频</a>）</p>
<p><img src="http://ww4.sinaimg.cn/mw690/81b78497jw1ej3xmerc23j20ss0cstd8.jpg" alt=""></p>
<p>图中 M/S 是 <a href="http://en.wikipedia.org/wiki/Master/slave_(technology" target="_blank" rel="external">Master-Slave</a>) 结构，实现简单，但是存在单点故障和数据丢失的问题。M/M 即 <a href="http://en.wikipedia.org/wiki/Multi-master_replication" target="_blank" rel="external">Multi-Master</a>，解决了单点故障但是一致性的实现较复杂且存在冲突合并的问题（Vector Clock解决）。从上图我们可以看到，我们基本上来说不可以让所有的项都绿起来，也就是之前说到的著名的CAP理论：一致性，可用性，分区容忍性，你只可能要其中的两个。</p>
<h2 id="分布式系统分类">分布式系统分类</h2>
<h3 id="分布式文件系统">分布式文件系统</h3>
<p>分布式文件系统用于存储 Blob 对象，典型的系统有 Facebook Haystack 以及 Taobao File System(TFS)。分布式文件系统是分布式的基石，通常作为上层系统的底层存储。</p>
<p>总体上看，分布式文件系统存储三种类型的数据 :Blob 对象、定长块以及大文件。在系统实现层面，分布式文件系统内部按照数据块(chunk)来组织数据，每个 chunk 的大小大致相同，每个 chunk 可以包含多个 Blob 对象或者定长块，一个大文件也可以拆分为多个 chunk 。</p>
<h3 id="分布式键值系统">分布式键值系统</h3>
<p>分布式键值系统用于存储关系简单的半结构化数据，它只提供基于主键的 CRUD(Create/Read/Update/Delete)功能。</p>
<p>典型的系统有 Amazon Dynamo 以及 Taobao Tair。从数据结构的角度看，分布式键值系统与传统的哈希表比较类似，不同的是，分布式键值系统支持将数据分布到集群中的多个存储节点。分布式键值系统是分布式表格系统的一种简化实现，一般用作缓存，比如淘宝 Tair 以及 Memcache。一致性哈希是分布式键值系统中常用的数据分布技术。</p>
<h3 id="分布式表格系统">分布式表格系统</h3>
<p>分布式表格系统用于存储关系较为复杂的半结构化数据。分布式表格系统以表格为单位组织数据，每个表格包括很多行，通过主键标识一行，支持根据主键的 CRUD 功能以及范围查找功能。</p>
<p>典型的系统包括 Google Bigtable 以及 Megastore，Microsoft Azure Table Storage，Amazon DynamoDB 等。在分布式表格系统中，同一个表格的多个数据行也不要求包含相同类型的列，适合半结构化数据。</p>
<h3 id="分布式数据库">分布式数据库</h3>
<p>分布式数据库一般是从单机关系数据库扩展而来，用于存储结构化数据。分布式数据库采用二维表格组织数据，提供 SQL 关系查询语言，支持多表关联，嵌套子查询等复杂操作，并提供数据库事务以及并发控制。</p>
<p>典型的系统包括 MySQL 数据库分片(MySQL Sharding)集群，Amazon RDS 以及Microsoft SQL Azure。分布式数据库支持的功能最为丰富，符合用户使用习惯，但可扩展性往往受到限制。当然，这一点并不是绝对的。Google Spanner 的扩展性就达到了全球级，它不仅支持丰富的关系数据库功能，还能扩展到多个数据中心的成千上万台机器。除此之外，阿里巴巴 OceanBase  也是一个支持自动扩展的分布式关系数据库。</p>
<h2 id="摘录">摘录</h2>
<p>书中有很多对于分布式的观点对我启发很大，将之引用如下。</p>
<ul>
<li>“Google的分布式存储系统一步步地从 Bigtable 到 Megastore，再到 Spanner，这也验证了分布式技术和传统关系数据库技术融合的必然性，即底层通过分布式技术实现可扩展性，上层通过关系数据库的模型和接口将系统的功能暴露给用户。” OceanBase 正是看准了这两种技术融合的必然性，才走向了可扩展的关系数据库道路。
　　 </li>
<li><p>“简单就是美。系统开发过程中，如果某个方案很复杂，一般是实践者没有想清楚。”。关于这一点其实很早就听说过，就像贯穿UNIX哲学的KISS原则（Keep It Simple,Stupid），而作者通过开发复杂的分布式存储系统过程中得出这么宝贵经验，是“简单就是美”最好的注解。</p>
</li>
<li><p>中心化 VS 去中心。“主流的分布式系统一般都带有中心节点，这样能够简化设计，而且中心节点只维护少量元数据，一般不会成为性能瓶颈。在实践中 Dynamo 及其开源实现 Cassandra 受到的关注逐渐减少，去中心的设计短期内难以成为主流。”</p>
</li>
</ul>
<h2 id="参考资料">参考资料</h2>
<ul>
<li>杨传辉 :<a href="http://book.douban.com/subject/25723658/" target="_blank" rel="external">大规模分布式存储系统</a></li>
<li>酷壳：<a href="http://coolshell.cn/articles/10910.html" target="_blank" rel="external">分布式系统的事务处理</a></li>
</ul>
  
	</div>
		<footer class="article-footer clearfix">
<div class="article-catetags">

<div class="article-categories">
  <span></span>
  <a class="article-category-link" href="/categories/系统架构/">系统架构</a>
</div>


  <div class="article-tags">
  
  <span></span> <a href="/tags/分布式/">分布式</a><a href="/tags/2PC/">2PC</a><a href="/tags/Paxos/">Paxos</a><a href="/tags/NWR/">NWR</a>
  </div>

</div>



	<div class="article-share" id="share">
	
	  <div data-url="http://wuchong.me/blog/2014/08/07/distributed-storage-system-knowledge/" data-title="分布式存储系统 知识体系 | Jark&#39;s Blog" data-tsina="2176287895" class="share clearfix">
	  </div>
	
	</div>


</footer>

   	       
	</article>
	
<nav class="article-nav clearfix">
 
 <div class="prev" >
 <a href="/blog/2014/08/28/how-to-correctly-write-singleton-pattern/" title="如何正确地写出单例模式">
  <strong>上一篇：</strong><br/>
  <span>
  如何正确地写出单例模式</span>
</a>
</div>


<div class="next">
<a href="/blog/2014/07/30/ali-bigdata-competition-write-to-the-5-monthes/"  title="阿里推荐大赛：写给这五个月">
 <strong>下一篇：</strong><br/> 
 <span>阿里推荐大赛：写给这五个月
</span>
</a>
</div>

</nav>

	
<section id="comments" class="comment">
	<div class="ds-thread" data-thread-key="blog/2014/08/07/distributed-storage-system-knowledge/" data-title="分布式存储系统 知识体系" data-url="http://wuchong.me/blog/2014/08/07/distributed-storage-system-knowledge/"></div>
</section>


</div>  
      <div class="openaside"><a class="navbutton" href="#" title="显示侧边栏"></a></div>

<div id="asidepart">
<div class="closeaside"><a class="closebutton" href="#" title="隐藏侧边栏"></a></div>
<aside class="clearfix">

  
<div class="categorieslist">
	<p class="asidetitle">分类</p>
		<ul>
		
			<li><a href="/categories/Hexo/" title="Hexo">Hexo<sup>7</sup></a></li>
		
			<li><a href="/categories/LinuxUnix/" title="Linux/Unix">Linux/Unix<sup>6</sup></a></li>
		
			<li><a href="/categories/Python/" title="Python">Python<sup>3</sup></a></li>
		
			<li><a href="/categories/推荐系统/" title="推荐系统">推荐系统<sup>3</sup></a></li>
		
			<li><a href="/categories/杂项资源/" title="杂项资源">杂项资源<sup>2</sup></a></li>
		
			<li><a href="/categories/程序设计/" title="程序设计">程序设计<sup>5</sup></a></li>
		
			<li><a href="/categories/系统架构/" title="系统架构">系统架构<sup>1</sup></a></li>
		
			<li><a href="/categories/编程语言/" title="编程语言">编程语言<sup>2</sup></a></li>
		
			<li><a href="/categories/职场生涯/" title="职场生涯">职场生涯<sup>2</sup></a></li>
		
			<li><a href="/categories/随笔生活/" title="随笔生活">随笔生活<sup>5</sup></a></li>
		
		</ul>
</div>


  
<div class="tagslist">
	<p class="asidetitle">标签</p>
		<ul class="clearfix">
		
			<li><a href="/tags/Hexo/" title="Hexo">Hexo<sup>8</sup></a></li>
		
			<li><a href="/tags/面试/" title="面试">面试<sup>5</sup></a></li>
		
			<li><a href="/tags/Linux基础/" title="Linux基础">Linux基础<sup>5</sup></a></li>
		
			<li><a href="/tags/生活/" title="生活">生活<sup>4</sup></a></li>
		
			<li><a href="/tags/博客/" title="博客">博客<sup>4</sup></a></li>
		
			<li><a href="/tags/Python/" title="Python">Python<sup>4</sup></a></li>
		
			<li><a href="/tags/阿里推荐大赛/" title="阿里推荐大赛">阿里推荐大赛<sup>4</sup></a></li>
		
			<li><a href="/tags/算法/" title="算法">算法<sup>2</sup></a></li>
		
			<li><a href="/tags/爬虫/" title="爬虫">爬虫<sup>2</sup></a></li>
		
			<li><a href="/tags/ODPS/" title="ODPS">ODPS<sup>2</sup></a></li>
		
			<li><a href="/tags/教程/" title="教程">教程<sup>2</sup></a></li>
		
			<li><a href="/tags/Jacman/" title="Jacman">Jacman<sup>2</sup></a></li>
		
			<li><a href="/tags/Java/" title="Java">Java<sup>2</sup></a></li>
		
			<li><a href="/tags/文件系统/" title="文件系统">文件系统<sup>2</sup></a></li>
		
			<li><a href="/tags/启动流程/" title="启动流程">启动流程<sup>1</sup></a></li>
		
			<li><a href="/tags/权限/" title="权限">权限<sup>1</sup></a></li>
		
			<li><a href="/tags/正则表达式/" title="正则表达式">正则表达式<sup>1</sup></a></li>
		
			<li><a href="/tags/jQuery/" title="jQuery">jQuery<sup>1</sup></a></li>
		
			<li><a href="/tags/双检锁/" title="双检锁">双检锁<sup>1</sup></a></li>
		
			<li><a href="/tags/设计模式/" title="设计模式">设计模式<sup>1</sup></a></li>
		
		</ul>
</div>


  <div class="linkslist">
  <p class="asidetitle">友情链接</p>
    <ul>
        
          <li>
            <a href="https://coderq.com" target="_blank" title="码农圈">码农圈</a>
          </li>
        
          <li>
            <a href="http://zipperary.com/" target="_blank" title="Zippera&#39;s Blog">Zippera&#39;s Blog</a>
          </li>
        
          <li>
            <a href="http://hijiangtao.github.io/" target="_blank" title="Data.Blog">Data.Blog</a>
          </li>
        
    </ul>
</div>

  <div class="weiboshow">
  <p class="asidetitle">新浪微博</p>
    <iframe width="100%" height="119" class="share_self"  frameborder="0" scrolling="no" src="http://widget.weibo.com/weiboshow/index.php?language=&width=0&height=119&fansRow=2&ptype=1&speed=0&skin=9&isTitle=1&noborder=1&isWeibo=0&isFans=0&uid=2176287895&verifier=b3593ceb&dpc=1"></iframe>
</div>


  <div class="rsspart">
	<a href="/atom.xml" target="_blank" title="rss">RSS 订阅</a>
</div>

</aside>
</div>
    </div>
    <footer><div id="footer" >
	
	<div class="line">
		<span></span>
		<div class="author"></div>
	</div>
	
	
	<section class="info">
		<p> Hello,I&#39;m WuChong. For now I&#39;m a graduate student in Beijing. <br/>
			I&#39;ll share my learning experience with you at this blog.</p>
	</section>
	 
	<div class="social-font" class="clearfix">
		
		<a href="http://weibo.com/wuchong1014" target="_blank" class="icon-weibo" title="微博"></a>
		
		
		<a href="https://github.com/wuchong" target="_blank" class="icon-github" title="github"></a>
		
		
		
		<a href="https://twitter.com/jarkwu" target="_blank" class="icon-twitter" title="twitter"></a>
		
		
		
		
		
		
		<a href="https://plus.google.com/111190881341800841449?rel=author" target="_blank" class="icon-google_plus" title="Google+"></a>
		
		
	</div>
		<p class="copyright">Powered by <a href="http://zespia.tw/hexo/" target="_blank" title="hexo">hexo</a> and Theme by <a href="https://github.com/wuchong/jacman" target="_blank" title="Pacman">Jacman</a> © 2014 
		
		<a href="http://wuchong.me/about" target="_blank" title="WuChong">WuChong</a>
		
		</p>
</div>
</footer>
    <script src="/js/jquery-2.0.3.min.js"></script>
<script src="/js/jquery.imagesloaded.min.js"></script>
<script src="/js/gallery.js"></script>

<script type="text/javascript">
$(document).ready(function(){ 
  $('.navbar').click(function(){
    $('header nav').toggleClass('shownav');
  });
  var myWidth = 0;
  function getSize(){
    if( typeof( window.innerWidth ) == 'number' ) {
      myWidth = window.innerWidth;
    } else if( document.documentElement && document.documentElement.clientWidth) {
      myWidth = document.documentElement.clientWidth;
    };
  };
  var m = $('#main'),
      a = $('#asidepart'),
      c = $('.closeaside'),
      o = $('.openaside');
  $(window).resize(function(){
    getSize(); 
    if (myWidth >= 1024) {
      $('header nav').removeClass('shownav');
    }else
    {
      m.removeClass('moveMain');
      a.css('display', 'block').removeClass('fadeOut');
      o.css('display', 'none');
        
    }
  });
  c.click(function(){
    a.addClass('fadeOut').css('display', 'none');
    o.css('display', 'block').addClass('fadeIn');
    m.addClass('moveMain');
  });
  o.click(function(){
    o.css('display', 'none').removeClass('beforeFadeIn');
    a.css('display', 'block').removeClass('fadeOut').addClass('fadeIn');      
    m.removeClass('moveMain');
  });
  $(window).scroll(function(){
    o.css("top",Math.max(80,260-$(this).scrollTop()));
  });
});
</script>

<script type="text/javascript">
$(document).ready(function(){ 
  var ai = $('.article-content>iframe'),
      ae = $('.article-content>embed'),
      t  = $('#toc'),
      h  = $('article h2')
      ah = $('article h2'),
      ta = $('#toc.toc-aside'),
      o  = $('.openaside'),
      c  = $('.closeaside');
  if(ai.length>0){
    ai.wrap('<div class="video-container" />');
  };
  if(ae.length>0){
   ae.wrap('<div class="video-container" />');
  };
  if(ah.length==0){
    t.css('display','none');
  }else{
    c.click(function(){
      ta.css('display', 'block').addClass('fadeIn');
    });
    o.click(function(){
      ta.css('display', 'none');
    });
    $(window).scroll(function(){
      ta.css("top",Math.max(140,320-$(this).scrollTop()));
    });
  };
});
</script>


<script type="text/javascript">
$(document).ready(function(){ 
  var $this = $('.share'),
      url = $this.attr('data-url'),
      encodedUrl = encodeURIComponent(url),
      title = $this.attr('data-title'),
      tsina = $this.attr('data-tsina'),
      description = $this.attr('description');
  var html = [
  '<a href="#" class="overlay" id="qrcode"></a>',
  '<div class="qrcode clearfix"><span>扫描二维码分享到微信朋友圈</span><a class="qrclose" href="#nothing"></a><strong>Loading...Please wait</strong><img id="qrcode-pic" data-src="http://s.jiathis.com/qrcode.php?url=' + encodedUrl + '"/></div>',
  '<a href="https://www.facebook.com/sharer.php?u=' + encodedUrl + '" class="article-share-facebook" target="_blank" title="Facebook"></a>',
  '<a href="https://twitter.com/intent/tweet?url=' + encodedUrl + '" class="article-share-twitter" target="_blank" title="Twitter"></a>',
  '<a href="#qrcode" class="article-share-qrcode" title="微信"></a>',
  '<a href="http://widget.renren.com/dialog/share?resourceUrl=' + encodedUrl + '&srcUrl=' + encodedUrl + '&title=' + title +'" class="article-share-renren" target="_blank" title="人人"></a>',
  '<a href="http://service.weibo.com/share/share.php?title='+title+'&url='+encodedUrl +'&ralateUid='+ tsina +'&searchPic=true&style=number' +'" class="article-share-weibo" target="_blank" title="微博"></a>',
  '<span title="Share to"></span>'
  ].join('');
  $this.append(html);
  $('.article-share-qrcode').click(function(){
    var imgSrc = $('#qrcode-pic').attr('data-src');
    $('#qrcode-pic').attr('src', imgSrc);
    $('#qrcode-pic').load(function(){
        $('.qrcode strong').text(' ');
    });
  });
});     
</script>



<script type="text/javascript">
  var duoshuoQuery = {short_name:"wuchong"};
  (function() {
    var ds = document.createElement('script');
    ds.type = 'text/javascript';ds.async = true;
    ds.src = '//static.duoshuo.com/embed.js';
    ds.charset = 'UTF-8';
    (document.getElementsByTagName('head')[0] 
    || document.getElementsByTagName('body')[0]).appendChild(ds);
  })();
</script> 







<link rel="stylesheet" href="/fancybox/jquery.fancybox.css" media="screen" type="text/css">
<script src="/fancybox/jquery.fancybox.pack.js"></script>
<script type="text/javascript">
$(document).ready(function(){ 
  $('.article-content').each(function(i){
    $(this).find('img').each(function(){
      if ($(this).parent().hasClass('fancybox')) return;
      var alt = this.alt;
      if (alt) $(this).after('<span class="caption">' + alt + '</span>');
      $(this).wrap('<a href="' + this.src + '" title="' + alt + '" class="fancybox"></a>');
    });
    $(this).find('.fancybox').each(function(){
      $(this).attr('rel', 'article' + i);
    });
  });
  if($.fancybox){
    $('.fancybox').fancybox();
  }
}); 
</script>



<!-- Analytics Begin -->

<script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-46321946-2', 'wuchong.me');  
ga('send', 'pageview');
</script>





<!-- Analytics End -->

<!-- Totop Begin -->

	<div id="totop">
	<a title="返回顶部"><img src="/img/scrollup.png"/></a>
	</div>
	<script src="/js/totop.js"></script>

<!-- Totop End -->

<!-- MathJax Begin -->
<!-- mathjax config similar to math.stackexchange -->


<!-- MathJax End -->

  </body>
</html>
